﻿using System;
using System.Collections.Generic;
using System.Linq;
using TaiwuModFramework.Common.Abstract;
using TaiwuModFramework.Common.Base;
using TaiwuModFramework.Common.Manager;
using TaiwuModFramework.Common.Utils;

namespace TaiwuModFramework.Common {
    public class PluginEntrance {


        /// <summary>
        /// 存放所有需要管理的模组的容器
        /// </summary>
        private static readonly Drawer<string, BaseTaiwuComp> modsComp = new Drawer<string, BaseTaiwuComp>();
        private static readonly List<BaseTaiwuComp> allCompList = new List<BaseTaiwuComp>();
        private static readonly Dictionary<string, BaseConfig> configCache = new Dictionary<string, BaseConfig>();
        private static ALogger Log { get { return AFwDomain.Log; } }


        /// <summary>
        ///  添加插件
        /// </summary>
        /// <param name="modIdStr"></param>
        /// <param name="pluginName"></param>
        /// <param name="config"></param>
        public static void AddPlugin(string modIdStr, string pluginName, BaseConfig config) {
            if(config == null || modIdStr == null || pluginName == null) return;
            string configName = config.GetType().FullName;
            if(configCache.ContainsKey(configName)) {
                Log.Info($"{configName}已经加载过,插件名{pluginName},插件id[{modIdStr}]。请检查是否重复加载，或全限定类名与其他模组相同");
                OnModSettingUpdate(modIdStr);
                return;
            } else {
                Log.Info($"加载配置{configName}\t插件名:{pluginName},插件id[{modIdStr}]");
                configCache.Add(configName, config);
            }
            try {
                ALogger logger = Log;
                ALogWriter logWriter = Log.LogWriter;
                // 获取配置的写入工具
                // 获取配置的日志工具
                if(!AFwDomain.ModIdStr.Equals(modIdStr)) {
                    logger = new BaseLogger(pluginName);
                }
                // 将日志写入工具与日志工具绑定
                logger.SetLogWriter(logWriter);
                Log.Info("配置日志工具,Name:{0}\t LogPath:[{1}]", logger.Name, logger.LogWriter.LogPath);

                // 注册组件
                CompManager.AddComp(modIdStr, config.GetComps());
                // 获取组件
                var comps = CompManager.GetComps(modIdStr);
                if(comps != null) {              
                    foreach(var comp in comps) {
                        comp.SetLogger(logger);
                        allCompList.Add(comp);
                        modsComp.Add(modIdStr, comp);
                        Log.Info("添加组件:[{0}]\t{1}", comp.GetType(), comp);
                    }
                }
                // 注册配置项
                ConfigManager.AddItems(modIdStr, comps);


                // 注册服务
                var services = config.GetSerivce();
                ServiceManager.AddServices(modIdStr, comps);
                ServiceManager.AddServices(modIdStr, services);
                if(services != null) {
                    services.ForEach(s => s.SetLogger(logger));
                }
                Log.Info("服务列表");
                foreach(var serviceName in ServiceManager.GetServiceList(modIdStr)) {
                    Log.Info("{0}", serviceName);
                }
                // 启动插件
                modsComp.Values(modIdStr).ForEach(s => {
                    try {
                        s.Enable();
                    } catch(Exception ex) {
                        Log.Error(s.GetType().FullName);
                        Log.Error(ex);
                    }
                });

            } catch(Exception e) {
                Log.Error(e);
            } finally {
                OnModSettingUpdate(modIdStr);
            }
        }


        public static List<string> GetAllModId() {
            List<string> list = new List<string>();
            list.AddRange(modsComp.Keys());
            return list;
        }


        public static void OnModSettingUpdate() {
            foreach(var id in modsComp.Keys()) {
                try {
                    OnModSettingUpdate(id);
                }catch(Exception e) {
                    Log.Error(e);
                }
            }
            try {
                ConfigManager.UpdateItem();
            }catch(Exception ex) {
                Log.Error(ex);
            }
        }
        public static void OnEnterNewWorld() {
            foreach(var id in modsComp.Keys()) {
                try {
                    OnEnterNewWorld(id);
                } catch(Exception e) {
                    Log.Error(e);
                }
            }
        }
        public static void OnLoadedArchiveData() {
            foreach(var id in modsComp.Keys()) {
                try {
                    OnLoadedArchiveData(id);
                } catch(Exception e) {
                    Log.Error(e);
                }
            }
        }


        public static void OnEnterNewWorld(string modIdStr) {
            Log.Info("Mod[{0}]\tOnEnterNewWorld", modIdStr);
            foreach(var comp in modsComp.Values(modIdStr)) {
                try {
                    comp.CallOnEnterNewWorld();
                } catch(Exception e) {
                    Log.Error(e);
                }
            }
        }

        public static void OnLoadedArchiveData(string modIdStr) {

            Log.Info("Mod[{0}]\tOnLoadedArchiveData", modIdStr);
            foreach(var comp in modsComp.Values(modIdStr)) {
                try {
                    comp.CallOnLoadedArchiveData();
                } catch(Exception e) {
                    Log.Error(e);
                }
            }

        }

        public static void OnModSettingUpdate(string modIdStr) {
            Log.Info("Mod[{0}]\tOnModSettingUpdate", modIdStr);
            ConfigManager.UpdateItem(modIdStr);
            foreach(var comp in modsComp.Values(modIdStr)) {
                try {
                    comp.CallOnModSettingUpdate();
                } catch(Exception e) {
                    Log.Error(e);
                }
            }
        }
    }
}
